home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_c
/
mscheap2
/
heap.man
< prev
next >
Wrap
Text File
|
1990-03-13
|
59KB
|
1,707 lines
Manual for Replacement Heap Manager for MSC
-------------------------------------------
Copyright (c) 1990 by Optimal Software, All Rights Reserved
Optimal Software, 4 Lacy Lane, Nashua, NH 03061-2151
603-880-9844 CIS [73710,406]
This file contains manual pages for the replacement
heap manager library.
I. Overview
This section provides introductory information on the heap manager
library. The function descriptions are in Part II.
1. Organization
Part I of the heap manager library manual is organized as follows
- Section 2 provides general rules for using the replacement
heap manager library.
- Section 3 describes the variables and types that are
declared by the heap manager and used by
the library routines.
- Section 4 summarizes the heap management functions and
provides a brief description of each function.
- Section 5 explains the contents of the heap manager include
files heap.h and heap.i.
Part II consists of detailed reference pages for the individual
heap access functions.
2. Using the heap management fuctions
This section provides the background information and the general
rules that apply to programs using the replacement heap manager.
a. Function prototypes
All of the heap management functions are declared as
prototypes with both a return type and a complete argument
list. The functions that are unique to the replcement heap
manager are disabled by the STDMSC symbol to provide strict
compatibility with the original malloc.h.
b. Stack checking
Stack checking is disabled for all heap management functions.
c. Type checking
The heap management functions are declared with complete
argument lists.
d. Error handling
The replacement heap manager handles errors the same way
the original MSC heap manager does. Where possible, the
function detecting the error returns a result indicating
that a problem exists. Invalid pointers passed to a heap
access function produce an error message on stderr.
i. _HEAPDEBUG -- debugging heap problems
This symbol enables an alternate set of functions that
diagnose heap problems. The functions that change the
heap are replace by equivalents that check the heap
consistency with _heapchk(), perform the standard heap
operation, and then record the transaction for diagnostic
reports triggered by errors.
The defined value of the symbol is taken to be the stream
on which error reports should appear. For example,
-D_HEAPDEBUG=stdout sends error reports to the standard
output stream.
Enabling _HEAPDEBUG also enables a stringent form of pointer
checking. Instead of a test on the value of the pointer
offset, _HEAPDEBUG checks that a matching entry exists in
the heap (this is free as _HEAPDEBUG must traverse the heap
to check for errors anyway). Thus _HEAPDEBUG guarantees that
no pointer that happens to have a zero offset can masquerade
as a heap pointer.
STDMSC overrides _HEAPDEBUG. If both are defined _HEAPDEBUG
is ignored.
For further details see section IV.D. of the heapinfo.txt file.
ii. _HEAPTRACE -- tracing heap activity
This symbol enables an alternate set of functions that
trace heap activity. Functions that change the heap are
replaced by equivalents that write a transaction record
to the trace log file after every heap access. The
transaction reports give the sequence number, the name
of the function, the value of the parameters, the source
file and line number and the returned result.
The defined value of the symbol is taken to be the stream
on which transaction reports should appear. For example,
-D_HEAPTRACE=stdout sends reports to the standard output file.
Enabling _HEAPTRACE implies that _HEAPDEBUG is enabled as well.
STDMSC overrides _HEAPTRACE. If both are defined _HEAPTRACE
is ignored.
For further details see section IV.E of the heapinfo.txt file.
3. Global variables and standard types
a. size_t _amblksiz;
The _amblksize variable controls the size of allocation
requests made to the operating system. It is identical
to the _amblksiz of the MSC heap manager, described on
page 33 of the MSC 5.1 Optimizing Compiler Run-Time Library
Reference, with one exception. The replacement heap manager
does not impose a power-of-two requirement on the size of
allocated blocks. This change gives application programs
precise control over the heap and limits heap fragmentation.
b. int _heapmode;
In order to expedite allocation operations there is a global
list of free chunks. The list is doubly linked, and ordered
as defined by _heapmode. MSC does not appear to have a free
list. It seems to rely on the hope that garbage collection is
infrequent to compensate for the fact than searching the entire
heap for free entries is extremely expensive.
The replacement heap manager optimizes its operations based on
the value of the variable _heapmode.
i. _HEAPTIME
The _HEAPTIME setting sacrifices space efficiency for
performance. The free list is not maintained in order
and allocation takes the first entry that fits (LIFO).
This setting is useful for programs with small amounts
of volatile data.
This setting also tries to meet allocation needs without
merging free blocks. If the allocation fails the free
list is condensed and another attempt is made. The MSC
heap manager operates in a similar manner, fragmenting
the heap and wasting space in an attempt to save time.
ii. _HEAPSIZE
If _heapmode is _HEAPSIZE the heap manager minimizes
the space occupied by the heap by maintaining the free
list in address order (first fit). This technique tends
to keep the in-use heap entries in low memory so that
_heappack() can release unused space back to DOS. This
setting is useful for programs which spawn other programs,
or use large buffers, or are generally tight on memory.
iii. _HEAPSPACE
If _heapmode is _HEAPSPACE the heap manager minimizes
the wasted heap space by maintaining the free list in
order of size (best fit). This technique permits the
most effective use of the available heap space. It is
useful for programs that must handle overflow via disk
files. The efficient utilization of heap memory minimizes
the need for disk access.
iv. Other values
Undefined values for _heapmode produce results identical
to _HEAPTIME.
Note that changing the _heapmode on the fly does not
automatically re-order the free list. Neither does it cause
problems. As the heap is used the free list will lose the
old ordering and conform to the new optimization.
The default mode is described by _HEAPMODE and may be set
from the compiler command line when the library is built by
defining the symbol _HEAPMODE. E.g., -D_HEAPMODE=_HEAPSIZE.
The factory setting is _HEAPTIME as this is the closest
approximation to the original MSC heap manager.
c. size_t _heappad
A classic problem in heap management is writing past the end
of a buffer obtained from the heap. This typically produces
extremely hostile effects. As the routines that handle
heap-generated buffers are usually embedded in the lower layers
of software, checking them can be tedious.
One method of testing this mode of failure is to add extra space
at the ends of the allocated areas. If the failures stop, there
is evidence of a heap problem. Of course, changing sizes moves
things around which can turn errors on and off randomly so the
evidence is flimsy. The problem with this debugging technique
is that changing the buffer lengths manually is a time-consuming,
error-prone operation with marginal utility.
The replacement heap manager provides a control for automatically
extending all heap allocation requests. Thus an initialization
parameter is enough to provide evidence for or against heap
problems. Typically the padding is set to one or two times the
size of the structures being manipulated.
Because the padding affects the distance between the data area
and the heap control structures it cannot be changed after the
heap has been initialized. The heap manager takes a copy of
_heappad when the heap is initialized and uses the copy thereafter.
Thus _heappad must be set as early as possible, typically in main().
Note that command-line wild cards processed with setargv.obj use
the heap before main is started. Normal programs without wild
card expansion can use:
extern size_t _heappad; /* declare the global variable */
int main()
{
_heappad = 100; /* set the value */
}
But programs with wild card handling enabled (those linked with
the special version of setargv.obj) must use:
size_t _heappad = 100; /* define the global and its value */
int main()
{
}
This sets the value at compile/link time rather than at run time.
The safety margins are automatically filled when a heap entry
is allocated. The fill pattern is initially alternating bits,
0x55, but it is reset by every call to _heapset(). _Heapchk()
compares the two safety margins and reports _HEAPBADPTR if they
differ.
d. Heap data structures and types
Heap.h defines several structures which represent heap
control blocks. The _heapinfo structure and the size_t type
are identical to the MSC versions. The other structures are
unique to the replacement heap manager.
i. _ARENA
The _ARENA structure describes a block of memory obtained
from the operating system or other source of heap memory.
Arenas are linked together in a doubly-linked list. Within
each arena the heap manager keeps track of the used and
free regions with _CHUNK control blocks.
ii. _CHUNK
The _CHUNK structure describes a block of memory that is
either in use by an application program or free to be
allocated. The chunks within an arena are linked together
in a doubly-linked list. The free chunks are also linked
into the global free list.
iii. _LINK
The _LINK structure describes a pair of pointers to
aligned structures. It is the basis for the doubly-linked
lists on which the heap management algorithms are based.
e. The linker vs module-arity
The replacement heap management functions are designed to
superceed the original functions contained in the standard
C run-time libraries. Unfortunately, the standard linker is
not able to handle the replacement process reliably. It
requires the /NOE switch to disable extended library searches
in order to avoid spurious messages of the form:
"symbol multiply defined, use /NOE"
With the /NOE switch, the linker is unable to resolve references
between libraries properly. For example, your application
program might refer to _fmalloc() and printf(). The _fmalloc()
reference will be resolved when the replacement heap library
is processed. The printf() reference will be resolved when
the default C run-time library is processed. But printf() calls
_getbuf() which calls malloc() which is in a module with _fmalloc().
The linker ignores the malloc() in the replacement library and uses
the one in the default library pulling in a second definition of
_fmalloc(). So there are two definitions of _fmalloc(), one from
each library, and the linker complains:
"symbol defined more than once"
The simplest solution to this problem is to remove the MSC
heap management functions from the default C run-time library.
This solution requires absolute faith in the compatibility and
reliability of the replacement heap manager. A less drastic
method is to arrange the functions in the replacement library
into modules that exactly match the modules in the original
library. This insures that collisions of the form described
above are impossible. It also allows easy integration of the
replacement library with the old library because the one-for-one
module matching is assured by use of the same module names.
Thus the replacement library is not fully decomposed into
individual functions. Multi-function modules in the original
library have been replicated in the replacement library. The
non-singular modules are as follows:
Module name Functions included
------------ --------------------------------------------
fheapchk _fheapchk _fheapset
fmalloc _ffree _fmalloc free(f) malloc(f)
fmsize _fmsize _msize(f)
freect _freect _memavl _memmax
nheapchk _nheapchk _nheapset
nmalloc _nfree _nmalloc free(n) malloc(n)
xheapchk _heapchk _heapset _heapwalk
Functions with an (f) suffix exist in libraries built with
the "far" data address model ("compact", "large", and "huge"
models). Functions with an (n) suffix exist in libraries
build with the "near" data address model ("small" and "medium").
4. Memory allocation summary
There are three heaps involved in the run-time library. The "near"
heap uses the default data segment. The "far" heap uses memory
from the operating system. The default heap is the same as one of
the first two heaps. It always matches the size of the default
data addressing model.
a. This list covers all of the memory allocation functions. Functions
unique to the replacement heap manager are mark with an '*'.
alloca Allocates memory from the stack
calloc Allocates memory for an array from the default heap
* _ncalloc applies to the near heap
* _fcalloc applies to the far heap (size <= SIZE_MAX)
* _hcalloc applies to the far heap (any size)
_expand Adjusts the size of an entry in the default heap
* _nexpand applies to the near heap
* _fexpand applies to the far heap (size <= SIZE_MAX)
* _hexpand applies to the far heap (any size)
free Releases memory back to the default heap (reverse malloc)
_nfree applies to the near heap
_ffree applies to the far heap
* _hfree applies to the far heap
_freect Estimates number of items that could be allocated (near)
halloc Allocates storage for a huge array from the far heap
_heapchk Verifies the integrity of the default heap
_nheapchk applies to the near heap
_fheapchk applies to the far heap
* _hheapchk applies to the far heap
* _heapdump Creates a detailed report on the default heap
* _nheapdump applies to the near heap
* _fheapdump applies to the far heap (includes debug info)
* _hheapdump applies to the far heap (includes debug info)
* _heappack Returns heap memory to the operating system.
* _nheappack applies to the near heap (non-fuctional)
* _fheappack applies to the far heap
* _hheappack applies to the far heap
_heapset Fills unused default heap memory with a single value
_nheapset applies to the near heap
_fheapset applies to the far heap
* _hheapset applies to the far heap
* _heapstat Translates heap status codes to text strings
_heapwalk Traverses the default heap, reporting on each entry
_nheapset applies to the near heap
_fheapset applies to the far heap
* _hheapset applies to the far heap
* _heapwatch Establishes read-only heap entries to be monitored
* _nheapwatch applies to the near heap (non-functional)
* _fheapwatch applies to the far heap
* _hheapwatch applies to the far heap
hfree Releases memory back to the far heap (reverse halloc)
malloc Allocates memory from the default heap
_nmalloc applies to the near heap
_fmalloc applies to the far heap (size <= SIZE_MAX)
* _hmalloc applies to the far heap (any size)
_memavl Estimates amount of memory available in near heap
_memmax Estimates size of largest free area in near heap
_msize Reports size of a default heap entry
_nmsize applies to the near heap
_fmsize applies to the far heap (size <= SIZE_MAX)
* _hmsize applies to the far heap (any size)
realloc Reallocates a block in the default heap
* _nrealloc applies to the near heap
* _frealloc applies to the far heap (size <= SIZE_MAX)
* _hrealloc applies to the far heap (any size)
* _relocate Repositions a block as low as possible in the detault heap
* _nrelocate applies to the near heap
* _frelocate applies to the far heap
* _hrelocate applies to the far heap
sbrk Resets break value
stackavail Reports stack space available for alloca
b. Brief descriptions
These functions are unique to the replacement heap manager
library. The standard functions are described on page 69 of
the MSC 5.1 Optimizing Compiler Run-Time Library manual.
_Heapdump() is a utility function that writes a complete
description of the state of the heap to the indicated
stream file.
_Heappack() releases unused heap memory. It searches the
entire heap, shrinking arenas that contain active entries
to the minimum, and totally freeing arenas that contain no
active entries.
_Heapstat() translates heap status codes obtained from the
_heapchk/set/walk() functions into descriptive strings.
_Heapwatch() establishes a heap entry as read-only. It
records a checksum which is tested by the _heapchk/set/walk()
functions, and monitored by the _HEAPDEBUG and _HEAPTRACE
routines.
_Relocate() repositions a heap entry as low as possible
in memory. It is the basis for garbage collection to
relieve heap fragmentation, and, with _heappack(),
supports heap compaction.
5. Include files
a. Heap.h
The include file heap.h is a replacement for the MSC include
file malloc.h. It provides transparent access to all of
the functionality of the original heap manager, plus the
extended capabilities of the replacement heap manager. The
symbol STDMSC enforces strict compatibility by disabling all
the extended features of the replacement heap manager.
Heap.h declares the following functions:
alloca _heapchk malloc *
calloc _heapdump _memavl
_expand * _heappack _memmax
_fcalloc * _heapset _msize *
_fexpand * _heapstat _ncalloc
_ffree * _heapwalk _nexpand
_fheapchk _heapwatch _nfree
_fheapdump _hexpand _nheapchk
_fheappack hfree @ _nheapdump
_fheapset _hfree _nheappack
_fheapwalk _hheapchk _nheapset
_fheapwatch _hheapdump _nheapwalk
_fmalloc * _hheappack _nheapwatch
_fmsize * _hheapset _nmalloc
_frealloc * _hheapwalk _nmsize
free * _hheapwatch _nrealloc
_freect _hmalloc _nrelocate
_frelocate _hmsize realloc *
halloc @ _hrealloc _relocate
_hcalloc _hrelocate sbrk
stackavail
* these functions include bug fixes for zero-length
entries and NULL pointers.
@ these functions are declared if STDMSC is defined.
SIZE_MAX is also declared in heap.h.
b. Heapdbg.h
The include file heapdbg.h is an auxilliary include file
activated by the _HEAPDEBUG and _HEAPTRACE symbols. It
declares alternates for the heap access functions. It also
maps the original function names to the alternate function
names so that no source code changes are necessary to activate
the heap debugger.
c. Heap.i
The include file heap.i is an internal header file for
the heap manager routines only. It is not necessary
for any application program to include it.
The heap.i file declares a variety of pre-processor macros
for use by the heap functions. It also defines the internally
shared variables and functions.
II. Reference
The replacement heap managment functions are listed here, one per page,
in alphabetical order. These descriptions rely on the information
contained in the MSC 5.1 Optimizing Compiler Run-Time Library Reference.
The example programs were tested under all address models.
It is instructive to examine the handling of the variants of the basic
functions. The original library uses a number of methods for handling
variants based on address models. Some functions have both far and near
variants with the mapping of the appropriate default model into the
generic function handled at run time. E.g., malloc exists and uses the
default heap. The explicit functions _fmalloc and _nmalloc allow programs
to access a particular heap independent of the default address model.
This is the most flexible arrangement.
The heapchk/set/walk family of functions are implemented as macros that
map to the address-model-specific version, either _nheapchk/set/walk or
_fheapchk/set/walk. This arrangement is a little strange as it provides
compile-time mapping, but must also support run-time mapping for modules
compiled without the inclusion of malloc.h. Indeed, the xheapchk module
implements just such a run-time mapping.
Another method of handling address width variation is to provide a single
default-heap-only function. In fact, calloc, _expand, and realloc have
no explicit variants. In a small model program you can _fmalloc and _ffree
but you cannot _fcalloc, _fexpand, or _frealloc.
Perhaps the worst possible situation is that which controls _freect,
_memavl, and _memmax. In spite of the documentation, these functions
only apply to the "near" heap. There are no equivalents for the far heap.
The replacement heap manager extends the capabilities of the heap manager
along two independent dimensions. First, it adds new functions. The
_heapdump, _heappack, _heapstat, _heapwatch, and _relocate functions are
unique to the replacement heap manager. Second, the replacement heap
manager provides address-model-specific variants for all basic function
in all three address models an extension along the "near"-"far"-"huge"
axis, with the default always being either "near" or "far". (Support
for a "huge" default model requires changes to other parts of the C
run-time library).
The rules for function naming give three variations for address models.
All functions accept the prefixes '_n', '_f', and '_h'. The "near"
functions use types size_t and near *. The "far" functions use types
size_t and far *. The "huge" functions use types long and huge *.
The above rules do not apply to the non-heap related functions alloca,
sbrk, and stackavail. Nor do they apply to the special purpose functions
_freect, halloc, hfree, _memavl, and _memmax. All other functions follow
the rules.
Unfortunately this leaves us with both an hfree function and an _hfree
function. This near collision is resolved by the symbol STDMSC. If it
is defined then halloc and hfree are declared and _hfree, along with all
the other extended functions, is not declared. If STDMSC is not defined
then halloc and hfree are not declared and will produce warnings about
lack of return values and prototypes.
ALLOCA
Summary
#include <heap.h
void *alloca( size );
size_t size; // Bytes to allocate
Differences
None.
Further info
See page 114 of the MSC 5.1 Optimizing Compiler Run-Time Reference
CALLOC
Summary
#include <heap.h>
void *calloc( nitems, size )
size_t nitems; // Number of array elements
size_t size; // Bytes in each element
void near *_ncalloc( nitems, size )
size_t nitems; // Number of array elements
size_t size; // Bytes in each element
void far *_fcalloc( nitems, size )
size_t nitems; // Number of array elements
size_t size; // Bytes in each element
void huge *_hcalloc( nitems, size )
long nitems; // Number of array elements
size_t size; // Bytes in each element
Differences
In "small" and "medium" model programs calloc and _ncalloc come
from the original library. In "compact", "large", and "huge" model
programs _ncalloc comes from the replacement library and, because
there is no near heap, always returns NULL.
The _fcalloc and _hcalloc functions always come from the replacement
library. They differ from the original versions as follows:
1. SIZE_MAX is 65535 rather than 65516.
2. Zero-length entries are do not corrupt the heap.
The _ncalloc, _fcalloc, and _hcalloc functions are unique to the
replacement heap manager.
Further info
See page 150 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_EXPAND
Summary
#include <heap.h>
void *_expand( buffer, size )
void *buffer; // Pointer to memory block
size_t size; // Desired number of bytes
void near *_nexpand( buffer, size )
void near *buffer; // Pointer to memory block
size_t size; // Desired number of bytes
void far *_fexpand( buffer, size )
void far *buffer; // Pointer to memory block
size_t size; // Desired number of bytes
void huge *_hexpand( buffer, size )
void huge *buffer; // Pointer to memory block
long size; // Desired number of bytes
Differences
In "small" and "medium" model programs _expand and _nexpand
come from the original library. In "compact", "large", and "huge"
model programs _nexpand comes from the replacement library and,
because there is no "near" heap, always returns NULL.
The _fexpand and _hexpand functions always come from the
replacement library. They differ from the original versions
as follows:
1. SIZE_MAX is 65535 rather than 65516.
2. Since the "huge" heap is part of the "far" heap,
_expand can handle any "huge" heap entry.
3. Invalid pointers are detected and reported on stderr.
4. Zero-length entries do not corrupt the heap.
The _nexpand, _fexpand, and _hexpand functions are unique to the
replacement heap manager.
Further info
See page 246 of the MSC 5.1 Optimizing Compiler Run-Time Reference
FREE
Summary
#include <heap.h>
void free( buffer );
void *buffer; // Pointer to memory block
void _nfree( buffer );
void near *buffer; // Pointer to memory block
void _ffree( buffer );
void far *buffer; // Pointer to memory block
void _hfree( buffer );
void huge *buffer; // Pointer to memory block
Differences
In "small" and "medium" model programs free and _nfree come from
the original library. In "compact", "large", and "huge" model
programs _nfree comes from the replacement library and, because
there is no "near" heap, does nothing.
The _ffree and _hfree functions always come from the replacement
library. They differ from the original versions as follows:
1. Since the "huge" heap is part of the "far" heap,
free can handle any "huge" heap entry.
2. Invalid pointers are detected and reported on stderr.
Note that while hfree and _hfree have very similar names they
have radically different purposes. The hfree function comes from
the original library and frees a region obtained from the
operating system by halloc. The _hfree function comes from the
replacement library and is the "huge" version of free.
This near collision is resolved by the STDMSC symbol. When STDMSC
is defined halloc and hfree are declared and _hfree is not. When
STDMSC is not defined halloc and hfree are not declared, but _hfree
and all the other extended functions are declared.
Further info
See page 289 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_FREECT
Summary
uint _freect( size );
size_t size; // Desired size of allocation
Differences
In "small" and "medium" model programs _freect comes from the
original library. In "compact", "large", and "huge" model
programs _freect comes from the replacement library and,
because there is no "near" heap, always returns zero.
Further info
See page 291 of the MSC 5.1 Optimizing Compiler Run-Time Reference
HALLOC
Summary
#include <heap.h>
#if defined ( STDMSC )
void huge *halloc( nitems, size );
long nitems; // Number of array elements
size_t size; // Bytes in each element
#endif
Differences
None.
But note that halloc is not declared unless the symbol STDMSC
is defined. The functions _hcalloc and _hmalloc superceed the
halloc function.
Further info
See page 347 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_HEAPCHK
Summary
#include <heap.h>
int _heapchk( void );
int _nheapchk( void );
int _fheapchk( void );
int _hheapchk( void );
Differences
In "small" and "medium" model programs _heapchk and _nheapchk come
from the original library. In "compact", "large", and "huge" model
programs _nheapchk comes from the replacement library and, because
there is no "near" heap, always returns _HEAPEMPTY.
The _fheapchk and _hheapchk functions always come from the
replacement library. They differ from the original versions
as follows:
1. They perform a detailed consistency check on each heap
entry, verifying the validity of the heap control block
and checking its neighbors for reciprocity.
2. The safety margins controlled by _heappad are inspected
for changes. Any alteration of the safety margins
produces a _HEAPBADPTR result code.
3. The checksums on the read-only heap entries established
by _heapwatch are recalculated. A changed checksum
produces a _HEAPBADPTR result code
Further info
See page 352 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_HEAPDUMP
Summary
#include <heap.h>
void _heapdump( stream, verbose );
FILE *stream; // Where to write the report
int verbose; // Whether to give details
void _nheapdump( stream, verbose );
FILE *stream;
int verbose;
void _fheapdump( stream, verbose );
FILE *stream;
int verbose;
void _hheapdump( stream, verbose );
FILE *stream;
int verbose;
Description
The _heapdump functions write a detailed report on the state of the
heap to a file. The verbose flag controls the amount of detail in
the report.
The reports on the "far" heap (_fheapdump and _hheapdump) include the
following information:
- Key to notation
- Global variables
- _heapmode
- _heappad
- Arena headers -- DOS interface
- Address [pointer]
- Size
- Links [pointers] on arena list
- Source of the memory (DOS or non-DOS)
- Chunk headers -- C interface
- Address {<pointer>}
- Size
- Links <pointers> on chunk list
- Links {pointers} on free list
- Status: readonly, damaged, OK, etc.
- In debug mode additional info is reported:
- Function that last changed the entry
- Desired size of the entry
- Transaction (sequence) number
- Name of source file (__FILE__)
- Line number in source file (__LINE__)
- Controls for free and join lists
- Address {pointer}
- Number of entries on the list (not including master)
- Links {pointers}
- Summary statistics on heap usage
- Number of entries in the heap
- Total heap memory
- Percent of heap memory in use
- Size of largest free block
- Pagination: formfeed
The _nheapdump function describes the "near" heap. It provides
the following information:
- Description of each heap entry
- Address
- Size
- Status (used/free)
- Summary statistics on heap usage
- Number of entries in the heap
- Total heap memory
- percent of heap memory in use
- Size of largest free block
- Pagination: formfeed
Return Value
None.
Differences
The _heapdump function is unique to the replacement heap manager.
Example
#include <stdio.h>
#include <heap.h>
int main()
{
_fmalloc( 1000 );
_fmalloc( 2000 );
_fheapdump( stdout, 1 );
return( 0 );
}
This program allocates two heap entries and then produces
a report on the state of the heap.
_HEAPPACK
Summary
#include <heap.h>
int _heappack( void );
int _nheappack( void );
int _fheappack( void );
int _hheappack( void );
Description
The _heappack() function shrinks the heap to the minimum required
to contain the in-use heap entries. Currently only the "far" heap
supports packing, but the _nheappack function exists as a stub
which returns a successful result code.
Return Value
Zero if successful, otherwise a DOS error number.
Differences
The _heappack function is unique to the replacement heap manager.
See Also
_relocate
Example
#include <stdio.h>
#include <heap.h>
int main()
{
void far *p1 = _fmalloc( 1000 );
void far *p2 = _fmalloc( 2000 );
void far *p3 = _fmalloc( 3000 );
_ffree( p2 );
_ffree( p3 );
printf("Before packing\n\n");
_fheapdump( stdout, 1 );
_fheappack();
printf("After packing\n\n");
_fheapdump( stdout, 1 );
return( 0 );
}
This program allocates three heap entries and then frees the
last two. Then it packs the heap to minimize the amount of
space taken up by the "far" heap. The before and after heap
reports illustrate the savings.
_HEAPSET
Summary
#include <heap.h>
int _heapset( fill );
uint fill; // Value to fill with
int _nheapset( fill );
uint fill; // Value to fill with
int _fheapset( fill );
uint fill; // Value to fill with
int _hheapset( fill );
uint fill; // Value to fill with
Differences
In "small" and "medium" model programs _heapset and _nheapset come
from the original library. In "compact", "large", and "huge" model
programs _nheapset comes from the replacement library and, because
there is no "near" heap, always returns _HEAPEMPTY.
The _fheapset and _hheapset functions always come from the
replacement library. They differ from the original versions
as follows:
1. They perform a detailed consistency check on each heap
entry, verifying the validity of the heap control block
and checking its neighbors for reciprocity.
2. The safety margins controlled by _heappad are inspected
for changes. Any alteration of the safety margins
produces a _HEAPBADPTR result code.
3. The checksums on the read-only heap entries established
by _heapwatch are recalculated. A changed checksum
produces a _HEAPBADPTR result code
4. The default safety margin fill value is reset by each call
to _heapset.
Further info
See page 354 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_HEAPSTAT
Summary
#include <heap.h>
char *_heapstat( status )
int status; // Status code from _heapchk/set/walk
Description
The _heapstat function translates heap status codes into descriptive
strings. Invalid status codes are also reported as such.
The translation is as follows:
_HEAPEMPTY Heap not initialized
_HEAPOK Heap is OK
_HEAPBADBEGIN Master heap data corrupt
_HEAPBADNODE Bad heap control block
_HEAPEND End of heap
_HEAPBADPTR Bad pointer or data corrupted
all others Unknown heap status code
Differences
The _heapstat function is unique to the replacement heap manager.
Return Value
The _heapstat function returns a pointer to the string containing
the status message.
Example
#include <stdio.h>
#include <heap.h>
int main()
{
printf("Heap status : %s\n", _heapstat( _heapchk() ) );
malloc( 1234 );
printf("Heap status : %s\n", _heapstat( _heapchk() ) );
return( 0 );
}
This program checks the heap status before and after the heap is
initialized. If the heap is not consistent it prints out
a error message.
_HEAPWALK
Summary
#include <heap.h>
int _heapwalk( info ); // Implemented as a macro
struct _heapinfo *info; // Info on one heap entry
Differences
In "small" and "medium" model programs _heapwalk and _nheapwalk come
from the original library. In "compact", "large", and "huge" model
programs _nheapset comes from the replacement library and, because
there is no "near" heap, always returns _HEAPEMPTY.
The _fheapwalk and _hheapwalk functions always come from the
replacement library. They differ from the original versions
as follows:
1. They perform a detailed consistency check on each heap
entry, verifying the validity of the heap control block
and checking its neighbors for reciprocity.
2. The safety margins controlled by _heappad are inspected
for changes. Any alteration of the safety margins
produces a _HEAPBADPTR result code.
3. The checksums on the read-only heap entries established
by _heapwatch are recalculated. A changed checksum
produces a _HEAPBADPTR result code
Further info
See page 356 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_HEAPWATCH
Summary
#include <heap.h>
int _heapwatch( buffer, enable )
void *buffer; // Pointer to memory block
int enable; // Turns monitoring on and off
int _nheapwatch( buffer, enable )
void near *buffer; // Pointer to memory block
int enable; // Turns monitoring on and off
int _fheapwatch( buffer, enable )
void far *buffer; // Pointer to memory block
int enable; // Turns monitoring on and off
int _hheapwatch( buffer, enable )
void huge *buffer; // Pointer to memory block
int enable; // Turns monitoring on and off
Description
The _heapwatch function establishes a heap entry as read-only.
The region is checksummed, and the _heapchk/set/walk family of
functions verify the integrity of the entry by recalculating
the checksum. The heap debug monitor also checks the read-only
entries and triggers a diagnostic report if one is changed.
If the enable argument is TRUE the checksum is calculated and
the region is treated as read-only. If the enable argument is
FALSE the region loses its read-only status.
A program may alter a read-only heap entry and inform the heap
manager that the change is not an error by calling _heapwatch
after each alteration.
Invalid pointers to "far" heap entries are detected and reported
on stderr.
Note that _expand, free, realloc, and _relocate automatically
remove the read-only status of a heap entry.
The _nheapwatch function is not currently implemented. It is
a stub that always returns a failure code.
Return Value
A successful invocation returns zero. If the pointer does not
address a valid heap entry _heapwatch returns non-zero.
Differences
The _heapwatch function is unique to the replacement heap manager.
Example
#include <stdio.h>
#include <heap.h>
void report( char *position );
int main()
{
int index;
char far *ptr = _fmalloc( 100 );
for ( index=0 ; index<100 ; index++ )
ptr[index] = (char) index;
_fheapwatch( ptr, 1 ); // establishes the enty as read-only
report( "read-only enabled" ); // should not detect an error
ptr[0] = -1; // change part of the data
report( "data modified" ); // should detect an error
_fheapwatch( ptr, 0 ); // stop watching this region
report( "read-only disabled" ); // should not detect an error
return( 0 );
}
void report( char *position )
{
int status = _fheapchk();
printf( "Heap status after %s : %s\n", position, _heapstat(status) );
}
This program allocates a region of 100 bytes and fills it with data.
It then declares the region to be read-only, and checks that _fheapchk
reports the heap as intact. Then the program changes the data, and
checks the heap status again. At this point the error should be
detected. Finally, the program unprotects the region and verifies
that _fheapchk stops complaining.
HFREE
Summary
#include <heap.h>
#if defined ( STDMSC )
void hfree( buffer );
void huge *buffer; // Pointer to memory block
#endif
Differences
None.
But note that while hfree and _hfree have very similar names they
have radically different purposes. The hfree function comes from
the original library and frees a region obtained from the
operating system by halloc. The _hfree function comes from the
replacement library and is the "huge" version of free.
This near collision is resolved by the STDMSC symbol. When STDMSC
is defined halloc and hfree are declared and _hfree is not. When
STDMSC is not defined halloc and hfree are not declared, but hfree
and all the other extended functions are declared.
Further info
See page 359 of the MSC 5.1 Optimizing Compiler Run-Time Reference
MALLOC
Summary
#include <heap.h>
void *malloc( size ); // Allocate memory from default heap
size_t size; // Bytes to allocate
void near *_nmalloc( size );// Allocate memory from "near" heap
size_t size; // Bytes to allocate
void far *_fmalloc( size ); // Allocate memory from "far" heap
size_t size; // Bytes to allocate
void huge *_hmalloc( size );// Allocate memory from "far" heap
long size; // Bytes to allocate
Differences
In "small" and "medium" model programs malloc and _nmalloc come
from the original library. In "compact", "large", and "huge" model
programs _nmalloc comes from the replacement library and, because
there is no near heap, always returns NULL.
The _fmalloc and _hmalloc functions always come from the replacement
library. They differ from the original versions as follows:
1. SIZE_MAX is 65535 rather than 65516.
2. Zero-length entries do not corrupt the heap.
Further info
See page 409 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_MEMAVL
Summary
#include <heap.h>
size_t _memavl( void );
Differences
In "small" and "medium" model programs _memavl comes from the
original library. In "compact", "large", and "huge" model
programs _memavl comes from the replacement library and,
because there is no "near" heap, always returns zero.
Further info
See page 414 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_MEMMAX
Summary
#include
size_t _memmax( void );
Differences
In "small" and "medium" model programs _memmax comes from the
original library. In "compact", "large", and "huge" model
programs _memmax comes from the replacement library and,
because there is no "near" heap, always returns zero.
Further info
See page 425 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_MSIZE
Summary
#include <heap.h>
size_t _msize( buffer );
void *buffer; // Pointer to memory block
size_t _nmsize( buffer );
void near *buffer; // Pointer to memory block
size_t _fmsize( buffer );
void far *buffer; // Pointer to memory block
long _hmsize( buffer );
void huge *buffer; // Pointer to memory block
Differences
In "small" and "medium" model programs _msize and _nmsize come
from the original library. In "compact", "large", and "huge"
model programs _nmsize comes from the replacement library and,
because there is no "near" heap, always returns zero.
The _fmsize and _hmsize functions always come from the
replacement library. They differ from the original versions
as follows:
1. Since the "huge" heap is part of the "far" heap,
_fmsize can handle any "huge" heap entry. However,
it cannot return the actual size because size_t is
too narrow, so it returns SIZE_MAX (65535). The
solution is to use _hmsize for all "far" and "huge"
heap entries.
2. NULL pointers have size zero rather than garbage.
3. Invalid pointers are detected and reported on stderr.
Further info
See page 440 of the MSC 5.1 Optimizing Compiler Run-Time Reference
REALLOC
Summary
#include <heap.h>
void *realloc( buffer, size );
void *buffer; // Pointer to memory block
size_t size; // Desired number of bytes
void near *_nrealloc( buffer, size );
void near *buffer; // Pointer to memory block
size_t size; // Desired number of bytes
void far *_frealloc( buffer, size );
void far *buffer; // Pointer to memory block
size_t size; // Desired number of bytes
void huge *_hrealloc( buffer, size );
void huge *buffer; // Pointer to memory block
long size; // Desired number of bytes
Differences
In "small" and "medium" model programs realloc and _nrealloc
come from the original library. In "compact", "large", and "huge"
model programs _nrealloc comes from the replacement library and,
because there is no "near" heap, always returns NULL.
The _frealloc and _hrealloc functions always come from the
replacement library. They differ from the original versions
as follows:
1. SIZE_MAX is 65535 rather than 65516.
2. Since the "huge" heap is part of the "far" heap,
realloc can handle any "huge" heap entry.
3. Invalid pointers are detected and reported on stderr.
4. Zero-length entries do not corrupt the heap.
5. The original realloc returned NULL when given a pointer
and a zero size as arguments. The replacement realloc
returns a zero-length heap entry, in keeping with the
other forms of realloc and the other allocation functions.
The _nrealloc, _frealloc, and _hrealloc functions are unique to the
replacement heap manager.
Further info
See page 483 of the MSC 5.1 Optimizing Compiler Run-Time Reference
_RELOCATE
Summary
#include <heap.h
void *_relocate( buffer );
void *buffer; // Pointer to memory block
void near *_nrelocate( buffer );
void near *buffer; // Pointer to memory block
void far *_frelocate( buffer );
void far *buffer; // Pointer to memory block
void huge *_hrelocate( buffer );
void huge *buffer; // Pointer to memory block
Description
The _relocate function moves a heap entry as low as possible
in memory. It scans the free list looking for the block that
has the lowest address and is large enough to contain the data.
If it finds one it copies the old entry to the new region and
frees the old entry.
The "far" heap also supports sliding entries downward into
adjacent free blocks. If the search for a free block fails
the preceeding block is checked. If it is free it swaps places
with the data block. The combination of the two techiques
guarantees that a single pass from low address to high address
through the in-use heap entries will always compact the heap fully.
I.e., all free space will be collected into a single entry at the
top of the heap.
Since the "huge" heap is part of the "far" heap, _frelocate can
handle any "huge" heap entry.
Invalid pointers to "far" heap entries are detected and
reported on stderr,
Return Value
If the entry is moved _relocate returns a pointer to the new
entry. If the entry cannot be moved _relocate returns NULL.
Differences
The _relocate function is unique to the replacement heap manager.
Example
#include <stdio.h>
#include <heap.h>
int main()
{
void far *p1 = _fmalloc( 1000 );
void far *p2 = _fmalloc( 2000 );
void far *p3 = _fmalloc( 3000 );
void far *p4 = _fmalloc( 4000 );
void far *new;
_ffree( p1 );
_ffree( p3 );
printf("Before relocation\n\n");
_fheapdump( stdout, 1 );
new = _frelocate( p2 ); if (new != NULL) p2 = new;
new = _frelocate( p4 ); if (new != NULL) p4 = new;
printf("After relocation\n\n");
_fheapdump( stdout, 1 );
return( 0 );
}
This program allocates four heap entries and then frees the
first and third, leaving the second in the middle of the heap
and the fourth at the end of the heap. Then it relocates the
two remaining entries to maximize the size of the free area.
The before and after heap reports illustrate the compaction.
SBRK
Summary
#include <heap.h>
void *sbrk( delta );
int delta; // Bytes to add to the "break value"
Differences
None.
Further info
See page 499 of the MSC 5.1 Optimizing Compiler Run-Time Reference
STACKAVAIL
Summary
#include <heap.h>
size_t stackavail( void );
Difference
None.
Further info
See page 568 of the MSC 5.1 Optimizing Compiler Run-Time Reference